package com.itaq.cheetah.serviceA.config.factory;

import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.itaq.cheetah.serviceA.config.jackson.JacksonComponent;
import com.itaq.cheetah.serviceA.config.jackson.introspector.DecryptAnnotationIntrospector;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;

/**
 * @author cheetah
 * @date 2021/6/21
 */
public class ObjectMapperFactory {

    private static volatile ObjectMapper generalObjectMapper;

    private static volatile ObjectMapper securityObjectMapper;

    public static ObjectMapper getSecurityObjectMapper() {
        if (Objects.nonNull(securityObjectMapper)) {
            return securityObjectMapper;
        }
        synchronized (ObjectMapperFactory.class) {
            if (Objects.nonNull(securityObjectMapper)) {
                return securityObjectMapper;
            }
            securityObjectMapper = getRawObjectMapper();
            AnnotationIntrospector sis = securityObjectMapper.getSerializationConfig().getAnnotationIntrospector();
            AnnotationIntrospector is1 = AnnotationIntrospectorPair.pair(sis, new DecryptAnnotationIntrospector());
            securityObjectMapper.setAnnotationIntrospector(is1);
            securityObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            return securityObjectMapper;
        }
    }

    public static ObjectMapper getObjectMapper() {
        if (Objects.nonNull(generalObjectMapper)) {
            return generalObjectMapper;
        }
        synchronized (ObjectMapperFactory.class) {
            if (Objects.nonNull(generalObjectMapper)) {
                return generalObjectMapper;
            }
            generalObjectMapper = getRawObjectMapper();
            generalObjectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            return generalObjectMapper;
        }
    }


    public static ObjectMapper getRawObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule timeModule = new JavaTimeModule();
        timeModule.addSerializer(LocalDateTime.class, new JacksonComponent.LocalDateTimeSerializer());
        timeModule.addDeserializer(LocalDateTime.class, new JacksonComponent.LocalDateTimeDeserializer());

        timeModule.addSerializer(LocalDate.class, new JacksonComponent.LocalDateSerializer());
        timeModule.addDeserializer(LocalDate.class, new JacksonComponent.LocalDateDeserializer());

        timeModule.addSerializer(Date.class, new JacksonComponent.DateSerializer());
        timeModule.addDeserializer(Date.class, new JacksonComponent.DateDeserializer());
        objectMapper.registerModule(timeModule);
        return objectMapper;
    }

}
